﻿using System;
using System.Collections.Generic;
using System.Linq;
using XStudio.XCRF.Data.Enums;

namespace XStudio.XCRF.Data.Business.Permissions
{
    /// <summary>
    /// 用于判断权限特性的分析器
    /// </summary>
    public class PermissionAttributeAnalyzer
    {
        /// <summary>
        /// 类级别特性
        /// </summary>
        private IEnumerable<BasePermissionAttribute> _ClassAttributes;
        /// <summary>
        /// 获取类别特性
        /// </summary>
        public IEnumerable<BasePermissionAttribute> ClassAttributes { get { return _ClassAttributes; } }
        /// <summary>
        /// 方法级别特性
        /// </summary>
        private IEnumerable<BasePermissionAttribute> _MethordAttributes;
        /// <summary>
        /// 获取方法级别特性
        /// </summary>
        public IEnumerable<BasePermissionAttribute> MethordAttributes { get { return _MethordAttributes; } }
        /// <summary>
        /// 权限表
        /// </summary>
        private Dictionary<MemberTypes, PermissionType> _Permissions = new Dictionary<MemberTypes, PermissionType>();
        /// <summary>
        /// 获取权限表
        /// </summary>
        public Dictionary<MemberTypes, PermissionType> Permissions { get { return _Permissions; } }
        /// <summary>
        /// 成员类型枚举集合
        /// </summary>
        private IEnumerable<MemberTypes> _MemberTypeEnums = null;
        /// <summary>
        /// 获取成员类型枚举集合
        /// </summary>
        protected IEnumerable<MemberTypes> MemberTypeEnums
        {
            get
            {
                if (_MemberTypeEnums == null)
                {
                    string[] memberTypeNames = Enum.GetNames(typeof(MemberTypes));
                    _MemberTypeEnums = from name in memberTypeNames
                                       select (MemberTypes)Enum.Parse(typeof(MemberTypes), name);
                }
                return _MemberTypeEnums;
            }
        }
        /// <summary>
        /// 默认权限类型
        /// </summary>
        private PermissionType _DefaultPermissionType = PermissionType.Deny;

        /// <summary>
        /// 获取默认权限类型
        /// </summary>
        public PermissionType DefaultPermissionType { get { return _DefaultPermissionType; } }

        /// <summary>
        /// 是否允许匿名访问
        /// </summary>
        private bool _AllowAnonymous = false;
        /// <summary>
        /// 获取是否允许匿名访问
        /// </summary>
        public bool AllowAnonymous { get { return _AllowAnonymous; } }
        /// <summary>
        /// 构造新的权限分析器
        /// </summary>
        /// <param name="classAttrs">类级别权限特性</param>
        /// <param name="methordAttrs">方法级别权限特性</param>
        public PermissionAttributeAnalyzer(IEnumerable<BasePermissionAttribute> classAttrs, IEnumerable<BasePermissionAttribute> methordAttrs)
        {
            _ClassAttributes = classAttrs;
            _MethordAttributes = methordAttrs;
            AnalyzeAttributes();
        }

        /// <summary>
        /// 开始执行权限分析
        /// </summary>
        private void AnalyzeAttributes()
        {
            #region 获取匿名权限
            AnonymousAttribute anonymousAttr;
            anonymousAttr = (AnonymousAttribute)
                _ClassAttributes.FirstOrDefault(attr => 
                    attr.GetType().IsSubclassOf(typeof(AnonymousAttribute))
                 || attr.GetType() == typeof(AnonymousAttribute));
            if (anonymousAttr != null)
                _AllowAnonymous = anonymousAttr.AllowAnonymous;
            anonymousAttr = (AnonymousAttribute)
                _MethordAttributes.FirstOrDefault(attr =>
                    attr.GetType().IsSubclassOf(typeof(AnonymousAttribute))
                 || attr.GetType() == typeof(AnonymousAttribute));
            if (anonymousAttr != null)
                _AllowAnonymous = anonymousAttr.AllowAnonymous;
            if (_AllowAnonymous)
            {
                foreach (MemberTypes memberType in MemberTypeEnums)
                    Permissions[memberType] = PermissionType.Allow;
                return;
            }
            #endregion 获取匿名权限

            #region 获取默认权限
            DefaultPermissionAttribute defaultAttr;
            defaultAttr = (DefaultPermissionAttribute)
                _ClassAttributes.FirstOrDefault(attr => attr.GetType() == typeof(DefaultPermissionAttribute));
            if (defaultAttr != null)
                _DefaultPermissionType = defaultAttr.PermissionType;
            defaultAttr = (DefaultPermissionAttribute)
                _MethordAttributes.FirstOrDefault(attr => attr.GetType() == typeof(DefaultPermissionAttribute));
            if (defaultAttr != null)
                _DefaultPermissionType = defaultAttr.PermissionType;
            foreach (MemberTypes type in MemberTypeEnums)
                _Permissions[type] = _DefaultPermissionType;
            #endregion 获取默认权限

            #region 设置类级别权限
            foreach (BasePermissionAttribute attr in _ClassAttributes)
            {
                Type type = attr.GetType();
                if (type == typeof(AllowMemberTypeAttribute))
                {
                    AllowMemberTypeAttribute allowAttr = (AllowMemberTypeAttribute)attr;
                    foreach (MemberTypes memberType in MemberTypeEnums)
                        if ((memberType & allowAttr.AllowedTypes) == memberType)
                            _Permissions[memberType] = PermissionType.Allow;
                    continue;
                }
                if (type == typeof(DenyMemberTypeAttribute))
                {
                    DenyMemberTypeAttribute denyAttr = (DenyMemberTypeAttribute)attr;
                    foreach (MemberTypes memberType in MemberTypeEnums)
                        if ((memberType & denyAttr.DeniedTypes) == memberType)
                            _Permissions[memberType] = PermissionType.Deny;
                    continue;
                }
            }
            #endregion 设置类级别权限

            #region 设置方法级别权限
            foreach (BasePermissionAttribute attr in _MethordAttributes)
            {
                Type type = attr.GetType();
                if (type == typeof(AllowMemberTypeAttribute))
                {
                    AllowMemberTypeAttribute allowAttr = (AllowMemberTypeAttribute)attr;
                    foreach (MemberTypes memberType in MemberTypeEnums)
                        if ((memberType & allowAttr.AllowedTypes) == memberType)
                            _Permissions[memberType] = PermissionType.Allow;
                    continue;
                }
                if (type == typeof(DenyMemberTypeAttribute))
                {
                    DenyMemberTypeAttribute denyAttr = (DenyMemberTypeAttribute)attr;
                    foreach (MemberTypes memberType in MemberTypeEnums)
                        if ((memberType & denyAttr.DeniedTypes) == memberType)
                            _Permissions[memberType] = PermissionType.Deny;
                    continue;
                }
            }
            #endregion 设置方法级别权限
        }

        /// <summary>
        /// 获取指定用户类型权限
        /// </summary>
        /// <param name="type">用户类型</param>
        /// <returns></returns>
        public PermissionType this[MemberTypes type]
        {
            get
            {
                return _Permissions[type];
            }
        }
    }
}
